#include "mainwindow.h"
#include "ui_mainwindow.h"
QSerialPort *selport = new QSerialPort();//实例化串口类一个对象
//发送数据给电机
uint8_t Send_header[3] = {0x00,0x00,0xff};//帧头
void MainWindow::sendData2Motor()
{
    selport->write((char*)Send_header , 3);
    uint8_t buffer[8];
    uint16_t val;
    buffer[0] = 0x01;
    val = ui->targetangleval->value();
    buffer[1] = val > 11000 ? 0x00 : 0x01;//方向
    if(buffer[1])
    {
        val = 11000-val;
    }else
    {
        val -= 11000;
    }
    buffer[2] = val>>8;//角度
    val = val << 8 >> 8;
    buffer[3] = val;//角度
    val = ui->strengthval->value();
    buffer[4] = val>>8;//力量
    val = val << 8 >> 8;
    buffer[5] = val;//力量
    val = ui->speedval->value();
    buffer[6] = val>>8;//速度
    val = val << 8 >> 8;
    buffer[7] = val;//速度
    selport->write((char*)buffer , 8);
}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->realangleval->setEnabled(false);
    ui->closebutton->setEnabled(false);//默认不可关闭
    ui->pausebutton->setEnabled(false);
    this->setWindowTitle(QString("伺服电机上位机"));

    tim1 = new QTimer();//发送数据
    tim2 = new QTimer();//同步数值
    tim2->start(100);
    connect(tim2,&QTimer::timeout,this,[=]()
    {
        QString str = QString::number(ui->targetangleval->value() - 11000);
        ui->label_targetangleval->setText(str);
        str = QString::number(ui->speedval->value());
        ui->label_speedleval->setText(str);
        str = QString::number(ui->strengthval->value());
        ui->label_strengthval->setText(str);
    });

    connect(tim1,&QTimer::timeout,this,[=]()
    {
        sendData2Motor();
    });


}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::Port_Scan()
{
    Ports = QSerialPortInfo::availablePorts();
    //清空portlist
    ui->portlist->clear();
    for(int i = 0;i < Ports.size();i++)
    {
        qDebug()<<QString("端口%1:").arg(i);
        qDebug()<<QString(Ports.at(i).portName()).arg(i);
        qDebug()<<QString(Ports.at(i).description());
        //填入portlist
        ui->portlist->addItem(Ports.at(i).portName());
    }
}

//刷新
void MainWindow::on_reloadbutton_clicked()
{
    Port_Scan();
}
//打开
void MainWindow::on_openbutton_clicked()
{
    if(selport->isOpen())
        {
            selport->clear();
            selport->close();
        }

        //设置串口名称
        selport->setPortName(ui->portlist->currentText());


        if(!selport->open(QIODevice::ReadWrite))//用ReadWrite 的模式尝试打开串口
        {
            qDebug()<<QString("打开失败!");
            QMessageBox::critical(this, tr("错误"), tr("打开失败"));
            return;
        }else
        {
             qDebug()<<QString("打开成功!");
             ui->closebutton->setEnabled(true);
             ui->openbutton->setEnabled(false);
        }
        //打开成功
        selport->setBaudRate(QSerialPort::Baud115200,QSerialPort::AllDirections);//设置波特率和读写方向
        selport->setDataBits(QSerialPort::Data8);		//数据位为8位
        selport->setFlowControl(QSerialPort::NoFlowControl);//无流控制
        selport->setParity(QSerialPort::NoParity);	//无校验位
        selport->setStopBits(QSerialPort::OneStop); //一位停止位

        //连接信号槽 当下位机发送数据QSerialPortInfo 会发送个 readyRead 信号,我们定义个槽void receiveInfo()解析数据
        connect(selport,SIGNAL(readyRead()),this,SLOT(receiveInfo()));
}



//处理串口数据
uint8_t buffer_header[4];
uint8_t dataheader[3] = {0x00,0x00,0xff};
int push2buffer_header(uint8_t data)//往buffer里填充数据
{
    for(int i = 0;i < 4-1;i++)
    {
        buffer_header[i] = buffer_header[i+1];
    }
    buffer_header[3] = data;
    if(memcmp(buffer_header,dataheader,3) == 0)
    {
        //qDebug()<<"解析到数据";
        return 1;
    }
    return 0;
}
uint8_t DATA_buf[8];
uint8_t DATA_buf_i;
uint8_t DATA_buf_state;
//处理电机传回数据
void MainWindow::motorData_Handle()
{
    uint16_t real_angle = 0;
    real_angle += DATA_buf[1];
    real_angle <<= 8;
    real_angle += DATA_buf[2];
    if(DATA_buf[0])
    {
        ui->realangleval->setValue(11000-real_angle);
        ui->label_realangleval->setText(QString::number(-real_angle));
    }else//右边
    {
        ui->label_realangleval->setText(QString::number(real_angle));
        ui->realangleval->setValue(real_angle+11000);
    }

}
void MainWindow::receiveInfo()
{
    QByteArray data = selport->readAll();
    //调试入口
    if(0)
    {
        qDebug()<<data.toHex(' ');
        return;
    }
    for(int i = 0;i < data.size();i++)
    {
        if(DATA_buf_state == 0 && push2buffer_header(data.at(i)))
        {
            DATA_buf_state = 1;
        }
        if(DATA_buf_state)
        {
            DATA_buf[DATA_buf_i++] =data.at(i);
            if(DATA_buf_i == 8)
            {
                //打印输出
                qDebug()<<"解析出数据!";
                //只需要处理前三个数据
                motorData_Handle();
                //复位
                DATA_buf_i = 0;
                DATA_buf_state = 0;
            }
        }
    }
    //qDebug()<<data.toHex(' ');
}

//关闭串口
void MainWindow::on_closebutton_clicked()
{
    selport->clear();
    selport->close();
    if(selport->isOpen())
    {
        qDebug()<<QString("关闭失败!");
        QMessageBox::critical(this, tr("错误"), tr("关闭失败！"));
    }else
    {
        qDebug()<<QString("关闭成功!");
        ui->closebutton->setEnabled(false);
        ui->openbutton->setEnabled(true);
    }
}
//复位
void MainWindow::on_angleresetbutton_clicked()
{
    ui->targetangleval->setValue(11000);
}
//开始发送
void MainWindow::on_startbutton_clicked()
{
    if(!selport->isOpen())
    {
        QMessageBox::critical(this, tr("错误"), tr("串口未打开！"));
        return;
    }
    tim1->start(30);
    ui->startbutton->setEnabled(false);
    ui->pausebutton->setEnabled(true);
}
//暂停发送
void MainWindow::on_pausebutton_clicked()
{
    tim1->stop();
    ui->startbutton->setEnabled(true);
    ui->pausebutton->setEnabled(false);
}
